<template>
    <div class="main_content">

        <div class="photo" @click="triggerFileUpload">
            <!-- 头像图片 -->
            <img :src="avatarUrl || defaultAvatar" alt="头像" />
            <div class="overlay">
                <Icon name="camera" :W="showx" :H="showy" v-if="!userStore.isvisitor" />
                <div class="overlay_text" v-if="!userStore.isvisitor">点击上传头像</div>
            </div>
            <input type="file" accept="image/*" class="hidden" ref="fileInput" @change="handleFileChange" />
        </div>
        <div class="infos">
            <div class="info_item info_item1">
                <div v-if="isEditIndex === 1">
                    <input v-model="tmp_username" type="text" @blur="saveText" @keyup.enter="saveText" maxlength="20" />
                </div>
                <div v-else style="font-weight:500; font-family:Arial, Helvetica, sans-serif;">{{ username }}</div>
                <button @click="editText(1)" class="button2" v-if="!userStore.isvisitor">
                    <FontAwesomeIcon :icon="faEdit" />
                </button>
            </div>
            <div class="info_item info_item1">
                <div v-if="isEditIndex === 2">
                    <input v-model="tmp_email" type="text" @blur="saveText" @keyup.enter="saveText" maxlength="20" />
                </div>
                <div v-else style="font-family:Arial, Helvetica, sans-serif;">{{ email }}</div>
                <button @click="editText(2)" class="button2" v-if="!userStore.isvisitor">
                    <FontAwesomeIcon :icon="faEdit" />
                </button>
            </div>
            <div class="info_item info_item1">
                <div v-if="isEditIndex === 3">
                    <input v-model="tmp_password" type="text" @blur="saveText" @keyup.enter="saveText" maxlength="22" />
                </div>
                <div v-else-if="ismask">{{ maskedPassword(password) }}</div>
                <div v-else>{{ password }}</div>
                <button v-if="isEditIndex !== 3 && !userStore.isvisitor" @click="ismask = !ismask" class="button1">
                    <FontAwesomeIcon :icon="!ismask ? faEye : faEyeSlash" />
                </button>
                <button @click="editText(3)" class="button2" v-if="!userStore.isvisitor">
                    <FontAwesomeIcon :icon="faEdit" />
                </button>
            </div>
            <div class="info_item ">
                <div v-if="isEditIndex === 4">
                    <textarea v-model="tmp_introduction" rows="15" maxlength="200" @blur="saveText"
                        @keyup.enter="saveText" class="introduction"></textarea>
                </div>
                <div v-else
                    style="white-space: normal; word-wrap: break-word;padding:0 30px;font-family:Arial, Helvetica, sans-serif">
                    {{ introduction }}
                </div>
                <button @click="editText(4)" class="button2" v-if="!userStore.isvisitor">
                    <FontAwesomeIcon :icon="faEdit" />
                </button>
            </div>
        </div>

        <div class="info2" v-if="!userStore.isvisitor">
            <div class="login_out">
                <button @click="amodal1 = true">退出登录</button>
            </div>
            <hr />
            <div class="register_out">
                <button @click="amodal = true">注销账号</button>
            </div>
        </div>
        <div class="star_projects">
            <n-tabs type="line" animated>
                <n-tab-pane name="repository" tab="repository" tab-style="color: red;">
                    <div style="height: 200px; overflow-y: auto; overflow-x: hidden;">
                        <div v-for="project in projectsStore.projects" :key="project.id" class="star_item"
                            @click="handleClickResponseory(project.id)">
                            <h2>{{ project.name }}</h2>
                            <p>{{ project.description }}</p>
                            <div class="star_footer">
                                {{ project.isPublic ? 'Public' : 'Private' }}
                            </div>
                        </div>
                    </div>
                </n-tab-pane>
                <n-tab-pane name="stars" tab="Stars" tab-style="color: red;">
                    <div style="height: 200px; overflow-y: auto; overflow-x: hidden;">
                        <div v-for="project in userStore.star_projects" :key="project.starID" class="star_item"
                            @click="visit_pj(project.projectID, project.authorID)">
                            <h2>{{ project.projectName }}</h2>
                            <p>{{ project.description }}</p>
                            <div class="star_footer">
                                {{ project.favorites }}
                                <div @click.stop="star_pj(project.starID)">
                                    <Icon name="stared" :W="16" :H="16" :Fill="'#f9e84f'" v-if="project.is_star" />
                                    <Icon name="star" :W="16" :H="16" v-else />
                                </div>
                            </div>
                        </div>
                    </div>
                </n-tab-pane>
                <n-tab-pane name="Team" tab="Team" tab-style="color: red;">

                </n-tab-pane>
            </n-tabs>
        </div>

        <a-modal v-model:open="amodal" title="⚠️ Warning" style="top: 100px">
            <p>Are you sure to register out?</p>
            <template #footer>
                <NButton @click="comfirm_register_out" type="warning" style="right:10px;">
                    Yes
                </NButton>
                <NButton @click="amodal = false" type="default">
                    No
                </NButton>
            </template>
        </a-modal>
        <a-modal v-model:open="amodal1" title="⚠️ Warning" style="top: 100px">
            <p>Are you sure to login out?</p>
            <template #footer>
                <NButton @click="comfirm_login_out" type="warning" style="right:10px;">
                    Yes
                </NButton>
                <NButton @click="amodal1 = false" type="default">
                    No
                </NButton>
            </template>
        </a-modal>
        <a-modal v-model:open="amodal2" class="amodal2-card" :width="550">
            <div class="clip-wrap" ref="clipWrap">
                <img :src="selectAvatarUrl" class="clip-img" ref="clipImg" alt="选择图片" style="width: 300px;" />
                <div class="clip-box" ref="clipBox"></div>
            </div>
            <canvas ref="avatarCanvas" style="display: none;border: 1px solid red;"></canvas>
            <template #footer>
                <button @click="comfirm_upload_img" class="modalbutton">
                    confirm
                </button>
            </template>
        </a-modal>
    </div>
</template>

<script lang="ts" setup>
import { nextTick, onMounted, ref, onUnmounted, watch, computed } from 'vue';
import defaultAvatar from '@/assets/images/default_profile.png';// 默认头像
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
import { faCopy, faEdit, faEye, faEyeSlash } from '@fortawesome/free-regular-svg-icons'
import { message } from 'ant-design-vue';
import { NButton, NTabs, NTabPane } from 'naive-ui';
const avatarUrl = ref<string | null>(null);
const fileInput = ref<HTMLInputElement | null>(null);
const triggerFileUpload = () => {
    if (userStore.isvisitor) {
        return
    }
    fileInput.value?.click();
};

import { useServer } from '../components/ts/useServer';
import { useUserStore } from '../stores/userStore';
import Icon from '../components/icons/Icon.vue'
import { Background } from '@vue-flow/background';
import { useProjectsStore } from '../stores/projectsStore';
import { useRouter } from 'vue-router'
const router = useRouter()
const { get, post, postFile } = useServer();
const userStore = useUserStore()
const projectsStore = useProjectsStore()
const mockTestUrl = "https://m1.apifoxmock.com/m1/6951272-6668040-default/api"
const amodal2 = ref<boolean>(false);
const showx = 48;
const showy = 48;
let clipWrap = ref<HTMLDivElement>();
let clipImg = ref<HTMLImageElement>();
let clipBox = ref<HTMLDivElement>();
let avatarCanvas = ref<HTMLCanvasElement>();
let ctx: CanvasRenderingContext2D | null;
let avatarBlob: Blob;//裁剪后的二进制blob图像数据
const selectAvatarUrl = ref<string>('');//原始选中的图像数据
let isTtrue = false;
const initX = ref(0)
const initY = ref(0)

//裁剪选择块的位置居中
function centerClipBox() {
    if (!clipBox.value || !clipWrap.value || !clipImg.value) {
        console.log('元素不存在')
        return;
    }

    let px = (clipWrap.value.clientWidth - clipBox.value.clientWidth) / 2;
    let py = (clipWrap.value.clientHeight - clipBox.value.clientHeight) / 2;
    clipBox.value.style.left = `${px}` + 'px'
    clipBox.value.style.top = `${py}` + 'px'
    clipBox.value.style.display = 'block';
}
//节流
function throttle(fn: any, delay = 300) {
    let timer: any;
    return function (...args: any[]) {

        if (timer) return;
        timer = setTimeout(() => {
            fn(...args);
            timer = null;
        }, delay);
    }
}

const mousedownListener = (e: MouseEvent) => {
    //console.log('按下了鼠标')
    if (!clipBox.value || !clipWrap.value || !avatarCanvas.value) {
        console.log('元素不存在')
        return;
    }
    isTtrue = true;
    initX.value = e.clientX - clipWrap.value.getBoundingClientRect().left - clipBox.value.offsetLeft;
    initY.value = e.clientY - clipWrap.value.getBoundingClientRect().top - clipBox.value.offsetTop;
    //  console.log('initX:',initX.value)
    // console.log('initY:',initY.value)
}

const mouseupListener = () => {
    //console.log('松开了鼠标')
    isTtrue = false;
}
const throttledMouseMove = throttle((e: MouseEvent) => {
    //console.log('移动了鼠标')
    if (isTtrue) {
        if (!clipWrap.value || !clipImg.value || !clipBox.value) {
            console.log('元素不存在')
            return;
        }
        let posx = e.clientX - initX.value - clipBox.value.getBoundingClientRect().left + clipBox.value.offsetLeft
        let posy = e.clientY - initY.value - clipBox.value.getBoundingClientRect().top + clipBox.value.offsetTop
        let maxX = (clipImg.value?.offsetWidth ?? 0) - (clipBox.value?.offsetWidth ?? 0) + (clipImg.value?.offsetLeft ?? 0);
        let maxY = (clipImg.value?.offsetHeight ?? 0) - (clipBox.value?.offsetHeight ?? 0) + (clipImg.value?.offsetTop ?? 0);
        let minX = clipImg.value.offsetLeft;
        let minY = clipImg.value.offsetTop;
        posx = Math.max(minX, Math.min(posx, maxX));
        posy = Math.max(minY, Math.min(posy, maxY));
        if (!clipBox.value) {
            console.log('clipBox不存在')
            return;
        }
        clipBox.value.style.left = posx + 'px';
        clipBox.value.style.top = posy + 'px';
        // console.log('posx:', posx)
        // console.log('posy:', posy)
        //裁剪区域移动重新绘制图片
        drawImage();
    }
}, 20)
//鼠标移动选择裁剪区域，并添加节流优化
const mousemoveListener = (e: MouseEvent) => {
    throttledMouseMove(e);
}

//计算上传图片要显示的尺寸
function computeSize(aspectRatio: number, imgUrl: string) {
    if (!imgUrl) {
        console.log('imgUrl不存在')
        return;
    }
    if (!clipWrap.value) {
        console.log('clipWrap不存在')
        return;
    }
    if (!clipImg.value) {
        console.log('clipImg不存在')
        return;
    }
    let drawWidth, drawHeight;
    if (aspectRatio > 1) {
        // 图片更宽
        drawWidth = clipWrap.value.offsetWidth;
        drawHeight = drawWidth / aspectRatio;

    } else {
        // 图片更高
        drawHeight = clipWrap.value.offsetHeight;
        drawWidth = clipWrap.value.offsetHeight * aspectRatio;
    }
    clipImg.value.src = imgUrl
    clipImg.value.style.width = `${drawWidth}px`;
    clipImg.value.style.height = `${drawHeight}px`

    clipImg.value.onload = () => {
        // 在计算完大小后居中显示clipBox
        centerClipBox();
        drawImage()
    }
}
//在canvas上绘制选择的区域并转为图片
function drawImage() {
    if (!avatarCanvas.value || !ctx || !clipImg.value || !clipBox.value) {
        console.log('元素不存在')
        return;
    }
    // 获取裁剪区域的矩形信息
    const clipRect = clipBox.value.getBoundingClientRect();
    const imgRect = clipImg.value.getBoundingClientRect();
    //console.log(`(${imgRect.width}, ${imgRect.height})`);
    let kk = Math.min(imgRect.width, imgRect.height)
    clipBox.value.style.width = kk + 'px'
    clipBox.value.style.height = kk + 'px'
    // 计算裁剪区域的坐标和尺寸
    const scaleX = (clipImg.value?.naturalWidth ?? 0) / imgRect.width;
    const scaleY = (clipImg.value?.naturalHeight ?? 0) / imgRect.height;

    // console.log(`(${imgRect.width},${imgRect.height})`)
    // console.log(`(${clipImg.value?.naturalWidth ?? 0},${clipImg.value?.naturalHeight ?? 0})`)
    // console.log('scaleX:', scaleX)
    // console.log('scaleY:', scaleY)
    const cropX = (clipRect.left - imgRect.left) * scaleX;
    const cropY = (clipRect.top - imgRect.top) * scaleY;
    const cropWidth = (clipBox.value?.clientWidth ?? 0) * scaleX;
    const cropHeight = (clipBox.value?.clientHeight ?? 0) * scaleY;

    // 调整画布尺寸
    avatarCanvas.value.width = cropWidth;
    avatarCanvas.value.height = cropHeight;

    // 清空画布
    ctx.clearRect(0, 0, avatarCanvas.value.width, avatarCanvas.value.height);

    // // 将画布剪裁为圆形区域，不想要圆形可以不要这块
    // ctx.beginPath();
    // ctx.arc(avatarCanvas.value.width / 2, avatarCanvas.value.height / 2, avatarCanvas.value.width / 2, 0, Math.PI * 2);
    // ctx.closePath();
    // ctx.clip();

    // 绘制图片
    ctx.drawImage(
        clipImg.value,
        cropX,
        cropY,
        cropWidth,
        cropHeight,
        0,
        0,
        avatarCanvas.value.width,
        avatarCanvas.value.width
    );
    //console.log(`(${cropX}, ${cropY}, ${cropWidth}, ${cropHeight}, ${avatarCanvas.value?.width}, ${avatarCanvas.value?.height})`)

    // 将画布内容转换为图片
    avatarCanvas.value.toBlob(function (blob) {
        avatarBlob = blob as Blob;
    }, 'image/png');
}

function handleFileChange(event: Event) {
    const target = event.target as HTMLInputElement;
    const file = target.files?.[0];
    if (file) {
        const reader = new FileReader();
        const Tmpimage = new Image();//用于临时加载选中的图片
        reader.onload = async (e) => {
            selectAvatarUrl.value = e.target?.result as string;
            const TmpimgUrl = selectAvatarUrl.value;
            Tmpimage.src = e.target?.result as string;
            Tmpimage.onload = function () {
                //显示图片预览
                amodal2.value = true;
                //初始化裁剪选择块的位置
                nextTick(() => {
                    if (!clipWrap.value || !clipBox.value || !clipImg.value || !avatarCanvas.value) {
                        console.log('元素挂载未完成!')
                        return;
                    }
                    centerClipBox()
                    ctx = avatarCanvas.value.getContext('2d');
                    if (!ctx) {
                        console.log('ctx不存在')
                        return;
                    }
                    avatarCanvas.value.width = 300;
                    avatarCanvas.value.height = 300;
                    document.addEventListener('mouseup', mouseupListener)
                    document.addEventListener('mousedown', mousedownListener)
                    clipBox.value.addEventListener('mousemove', mousemoveListener);
                    let amodalRef = <HTMLDivElement>document.querySelector('.ant-modal-content')
                    let amodalxRef = <HTMLDivElement>document.querySelector('.ant-modal-close-x')

                    if (amodalRef && amodalxRef) {
                        amodalRef.style.backgroundColor = 'rgba(0, 0, 0, 0.7)';
                        amodalxRef.style.color = 'red'
                    }
                    // 计算图片绘制区域，确保图片保持比例
                    const aspectRatio = Tmpimage.width / Tmpimage.height;
                    computeSize(aspectRatio, TmpimgUrl);
                })
            };
        };
        reader.readAsDataURL(file);
        target.value = '';//允许重复选择
    }
}
const comfirm_upload_img = () => {
    if (!avatarBlob) {
        message.error('请重试')
        return;
    }
    //上传图片
    const formData = new FormData();
    formData.append('avatar', avatarBlob);
    formData.append('userID', userStore?.currentUser || '');
    postFile('upload/image', formData, mockTestUrl).then(res => {
        if (res?.success) {
            avatarUrl.value = res.image_url
            message.success('上传成功')
        } else {
            message.error('上传失败')
        }
        avatarUrl.value = URL.createObjectURL(avatarBlob);
        handleamodalClose()
        amodal2.value = false
    })
}
const handleamodalClose = () => {
    document.removeEventListener('mouseup', mouseupListener)
    clipBox.value?.removeEventListener('mousemove', mousemoveListener);
    document.removeEventListener('mousedown', mousedownListener)
}
watch(amodal2, (newVal) => {
    if (newVal === false) {
        handleamodalClose();
    }
});

onUnmounted(() => {
    handleamodalClose()
});
const username = ref('用户名')
const email = ref('xxx@xxx.com')
const password = ref('密码必须为6-22位')
const introduction = ref('暂无简介')
const tmp_username = ref('')
const tmp_email = ref('')
const tmp_password = ref('')
const tmp_introduction = ref('')
const isEditIndex = ref<number>(0);
const editText = async (index: number) => {
    if (isEditIndex.value !== index) {
        isEditIndex.value = index;
    } else {
        isEditIndex.value = 0;
        CancleEdit()
    }
}
const EditSuccess = () => {
    isEditIndex.value = 0
    username.value = tmp_username.value
    email.value = tmp_email.value
    password.value = tmp_password.value
    introduction.value = tmp_introduction.value
    message.success('修改成功')
}
const CancleEdit = () => {
    isEditIndex.value = 0
    tmp_username.value = username.value
    tmp_email.value = email.value
    tmp_password.value = password.value
    tmp_introduction.value = introduction.value
    ismask.value = true
}
const saveText = async () => {
    try {
        post('user/updateUserInfo', {
            username: tmp_username.value,
            user_email: tmp_email.value,
            user_password: tmp_password.value,
            introduction: tmp_introduction.value,
            userID: userStore.currentUser
        }).then(res => {
            if (res.success) {
                EditSuccess()
            } else {
                message.error('请重试')
                CancleEdit()
            }
        })
    } catch (error) {
        message.error('请重试')
        CancleEdit()
    }
}

const copyText = (text: string) => {
    if (text) {
        navigator.clipboard.writeText(text);
    }
    message.success('复制成功')
}
const ismask = ref<boolean>(true)

function maskedPassword(pwd: string) {
    return '*'.repeat(pwd.length); // 每个字符显示为 *
}
let visitorID = ''
let visitorName = ''
onMounted(async () => {
    let tpID = router.currentRoute.value.params.id as string;
    if (tpID) {
        let tpName = router.currentRoute.value.params.name as string;
        visitorID = router.currentRoute.value.params.visitorID as string;
        visitorName = router.currentRoute.value.params.visitorName as string;
        userStore.isvisitor = true
        let res1 = await post('remote_login', { userID: tpID })
        if (!res1.success) {
            console.log("login failed")
            return
        }
        userStore.login(tpID, tpName)
    }
    get('getUserInfo', { userID: userStore.currentUser }).then(res => {
        if (res.success) {
            console.log("获取用户信息成功", res)
            username.value = userStore?.currentUserName ?? '用户名'
            password.value = res.user_info.user_password ?? "密码必须为6-12位"
            email.value = res.user_info.user_email ?? "xxx@xxx.com"
            introduction.value = res.user_info?.user_introduction ?? "暂无简介"
            avatarUrl.value = res.user_info?.user_avatar ?? null
            userStore.star_projects = res.user_info?.star_projects ?? []
            tmp_username.value = username.value
            tmp_email.value = email.value
            tmp_password.value = password.value
            tmp_introduction.value = introduction.value
        } else {
            alert('获取用户信息失败');
        }
    });

    const star_tabs = document.querySelectorAll<HTMLElement>('.n-tabs-tab')
    const b_lines = document.querySelectorAll<HTMLElement>('.n-tabs-bar')

    // 遍历所有被选中的 tab
    star_tabs.forEach(tab => {
        tab.style.color = 'blue'
    })

    // 遍历所有线条
    b_lines.forEach(line => {
        line.style.backgroundColor = 'blue'
    })
    projectsStore.fetchAllProjects();
    projectsStore.initializeProjects();
})

const logout = async () => {
    post('login_out', { userID: userStore.currentUser }).then(res => {
        if (res.success) {
            userStore.logout()
            window.location.href = '/login'
        } else {
            message.error('退出登录失败')
        }
    });
}
const register_out = async () => {
    post('register_out', { userID: userStore.currentUser }).then(res => {
        if (res.success) {
            userStore.logout()
            window.location.href = '/login'
        } else {
            message.error('注销账户失败')
        }
    });
}

const amodal = ref<boolean>(false);
const comfirm_register_out = async () => {
    await register_out()
    amodal.value = false;
};
const amodal1 = ref<boolean>(false);
const comfirm_login_out = async () => {
    await logout()
    amodal1.value = false;
};

const visit_pj = (projectID: string, authorID: string) => {
    if (!userStore.isLoggedIn) {
        return
    }
    if (userStore.isvisitor) {
        projectsStore.visit_pj(projectID, authorID, visitorID, visitorName);
    } else {
        projectsStore.visit_pj(projectID, authorID, userStore.currentUser as string, userStore.currentUserName as string);
    }
}
const star_pj = (projectID: string) => {
    if (userStore.isvisitor) {
        return
    }
    projectsStore.star_pj(projectID);
}
const handleClickResponseory = (projectID: string) => {
    if (userStore.isvisitor) {
        //当前访问的用户是伪登录状态
        visit_pj(projectID, userStore.currentUser as string)
    } else {
        projectsStore.open_project(projectID)
    }
}
</script>

<style scoped lang="scss">
.main_content {
    display: flex;
    overflow-y: auto;
    width: 100%;
    height: 100%;
    position: relative;
    background: radial-gradient(circle at center,
            rgba(173, 216, 230, 0)20%,
            rgba(142, 201, 220, 0.3) 80%,
            rgba(110, 197, 225, 0.684) 100%);
    margin: 0 auto;
    flex-direction: column;
    align-items: center;
    padding-top: 20px;

    .photo {
        margin-top: 50px;
        width: 128px;
        height: 128px;
        border-radius: 100%;
        overflow: hidden;
        position: relative;
        cursor: pointer;
        background-color: #007bff;
        border: 2px solid #85b5e9;
        box-shadow: 0 0 15px rgba(109, 204, 228, 0.5);

        &:hover {
            box-shadow: 0 0 30px rgba(109, 204, 228, 0.8);
        }
    }

    img {
        width: 100%;
        height: 100%;
        object-fit: cover; // 保持比例并填充容器
    }

    .infos {
        display: flex;
        flex-direction: column;
        width: 300px;
        position: relative;
        margin-top: 10px;

        .info_item1 {
            height: 30px;
        }

        .info_item {
            margin-top: 5px;
            width: 100%;

            overflow: hidden;
            position: relative;
            align-items: center;
            justify-items: center;

            /* 渐变背景：以中心为起点，椭圆形扩散 */
            background: radial-gradient(ellipse at center,
                    /* 椭圆形，中心点 */
                    rgba(121, 237, 235, 0.5) 0%,
                    /* 淡蓝色中心 */
                    rgba(168, 225, 226, 0.527) 20%,
                    /* 渐淡 */
                    rgba(173, 216, 230, 0.0) 100%
                    /* 边缘透明 */
                );

            button {
                position: absolute;
                top: 3px;
                background: transparent;
                border: none;
                outline: none;
                cursor: pointer;
            }

            .button1 {
                left: 0;
            }

            .button2 {
                right: 0;
            }
        }

        .introduction {
            outline: none;
            border: 1px solid #ccc;
            resize: none;
            user-select: text;
            font-size: 14px;
            font-weight: bold;

        }
    }

    .info2 {
        display: flex;
        flex-direction: row;
        align-items: center;
        justify-content: space-around;
        align-content: center;
        height: 30px;
        width: 300px;
        position: relative;

        .login_out {
            width: 100px;
            height: 100%;
            display: flex;
            align-content: center;
            justify-content: center;

            button {
                //background: transparent;
                background: radial-gradient(ellipse at center,
                        /* 椭圆形，中心点 */
                        rgba(121, 237, 235, 0.5) 0%,
                        /* 淡蓝色中心 */
                        rgba(168, 225, 226, 0.527) 20%,
                        /* 渐淡 */
                        rgba(173, 216, 230, 0.0) 100%
                        /* 边缘透明 */
                    );
                border: none;
                outline: none;
                cursor: pointer;

                &:hover {
                    color: blue;
                    transform: scale(1.1);
                }
            }
        }

        .register_out {
            height: 100%;
            width: 100px;
            display: flex;
            align-content: center;
            justify-content: center;

            button {
                background: transparent;
                border: none;
                outline: none;
                cursor: pointer;
                background: radial-gradient(ellipse at center,
                        /* 椭圆形，中心点 */
                        rgba(121, 237, 235, 0.5) 0%,
                        /* 淡蓝色中心 */
                        rgba(168, 225, 226, 0.527) 20%,
                        /* 渐淡 */
                        rgba(173, 216, 230, 0.0) 100%
                        /* 边缘透明 */
                    );

                &:hover {
                    color: rgb(239, 11, 11);
                    transform: scale(1.1);
                }
            }
        }

        hr {
            height: 100%;
            width: 1px;
            background-color: gray;
            /* 可以根据需要改颜色 */
            margin: 0 10px;
            /* 左右间距 */
            border: none;
        }
    }

    .star_projects {
        width: 400px;

        .star_item {
            padding: 5px;
            position: relative;
            border: 1px dashed #ccc;
            border-radius: 5px;
            transition: background-color 0.3s ease;

            &:hover {
                background-color: #abdbf15f;
                cursor: pointer;
            }
        }

        .star_footer {
            display: flex;
            height: 30px;
            width: 100%;
            justify-content: flex-end;
            align-items: center;
            padding-right: 10px;
        }
    }
}

.photo:hover .overlay {
    opacity: 1;
}

.overlay {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    background-color: rgba(0, 0, 0, 0.5);

    display: flex;
    align-items: center;
    justify-content: center;
    flex-direction: column;

    opacity: 0;
    transition: opacity 0.3s ease;

    .overlay_text {
        color: white;
        font-size: 12px;
    }

}

.clip-wrap {
    display: block; //初始为none
    width: 400px;
    height: 400px;
    margin: 0 auto;
    background-color: #141313;
    position: relative;

    .clip-img {
        position: absolute;
        left: 0;
        right: 0;
        bottom: 0;
        top: 0;
        margin: auto;
    }

    .clip-box {
        display: block;
        position: absolute;
        width: 300px;
        height: 300px;
        background: rgba(0, 0, 0, 0.5);
        box-sizing: border-box;
        border: 1px solid #fff;
        cursor: move;
        border-radius: 100%;
    }
}

.amodal2-card {
    top: 10px;

    .modalbutton {
        font-family: Arial, Helvetica, sans-serif;
        width: 80px;
        background-color: #ffffff00;
        color: #fff;
        border: solid 1px #fff;
        border-radius: 4px;
        cursor: pointer;
        font-size: 14px;
        transition: color 0.3s ease, border-color 0.3s ease;

        &:hover {
            color: red;
            border-color: red;
        }
    }
}
</style>